#include "StdAfx.h"
#include "SelectEditor.h"
#include "AnyView.h"
#include "SelectionSet.h"
#include "RenderEngine.h"
#include "ShapeBuilder.h"
#include "ShapeInfoFactory.h"
#include "../GeomUI/MessageGeomUI.h"
#include <Bnd_Box.hxx>
#include <Geom_Axis2Placement.hxx> 
#include <AIS_Trihedron.hxx> 
#include <AIS_Drawer.hxx> 
#include <Prs3d_DatumAspect.hxx> 
REGISTERE_EDITOR(CSelectEditor);

CSelectEditor::CSelectEditor(void)
{
	m_pPen = new CPen(PS_DASHDOT, 1, RGB(255,0,0));
	m_pSelectionSet = NULL;
	m_pShapeInfo = NULL;
}					 

CSelectEditor::~CSelectEditor(void)
{
	delete m_pSelectionSet;
	delete m_pPen;
	m_pPen = NULL;

	delete m_pShapeInfo;
	m_pShapeInfo = NULL;
}

CString CSelectEditor::GetID()
{
	return _T("EB8C5B5B-80FD-424f-99D8-C19E4EC7288A");
}
void CSelectEditor::Initialize(CAnyView* pView)
{
	CAnyEditor::Initialize(pView);
	m_pSelectionSet = GetRender()->CreateSelectionSet(*pView);
}

CSelectionSet* CSelectEditor::Selecter()
{
	return m_pSelectionSet;
}
EditorState CSelectEditor::OnLButtonDown(UINT nFlags, long x, long y)
{
	m_ptStart.x = x;
	m_ptStart.y = y;
	m_ptEnd = m_ptStart;
	
	if(AIS_SOP_OneSelected == Selecter()->Select(x, y))
	{
		Handle(AIS_InteractiveObject) selectedShape;
		if(!Selecter()->GetSelected(selectedShape))
			return ES_CONTINUE;

		//
		Handle_AIS_Shape hShape = Handle(AIS_Shape)::DownCast(selectedShape);
		if(!hShape.IsNull())
		{
			//Bnd_Box bBox = hShape->BoundingBox();
			//bBox.SetGap(0.0);
			//Standard_Real minX, minY, minZ, maxX, maxY, maxZ;
			//bBox.Get(minX, minY, minZ, maxX, maxY, maxZ);
			//
			////gp_Ax2 Ax2 ( gp_Pnt((maxX+minX)/2, (maxY+minY)/2, (maxZ+minZ)/2), gp_Dir(0,0,1) );
			//gp_Ax2 Ax2 ( gp_Pnt(minX, minY, minZ), gp_Dir(0,0,1) );
			//Handle(Geom_Axis2Placement) gAx2 = new Geom_Axis2Placement ( Ax2 );

			//Handle(AIS_Trihedron) aTr = new AIS_Trihedron(gAx2);

			//aTr->SetSize(max(max(maxX-minX, maxY-minY), maxZ-minZ)+20);

			//Handle(AIS_Drawer) aDrawer = aTr->Attributes();

			//if(!aDrawer->HasDatumAspect()) 
			//	aDrawer->SetDatumAspect(new Prs3d_DatumAspect());

			//aDrawer->DatumAspect()->SetDrawFirstAndSecondAxis(Standard_True);

			//aTr->SetColor(Quantity_NOC_RED); 
			//aTr->SetTextColor(Quantity_NOC_BLACK); 
			//aTr->SetArrowColor( Quantity_NOC_RED );

			//GetRender()->GetAIS()->Display(aTr, Standard_True);
		}
		//
		// Get the main label of the selected object
		Handle(TPrsStd_AISPresentation) ObjectPrs = 
			Handle(TPrsStd_AISPresentation)::DownCast(selectedShape->GetOwner());
		if(ObjectPrs.IsNull()) // not user shape
			return ES_CONTINUE;
		m_LabelSelected = ObjectPrs->Label();

		// Get the TFunction_Function attribute of the selected object
		Handle(TFunction_Function) TFF; 
		if ( !m_LabelSelected.FindAttribute(TFunction_Function::GetID(),TFF) )
		{
			return ES_CONTINUE;
		}
		// Get the Standard_GUID of the TFunction_FunctionDriver of the selected object TFunction_Function attribute
		Standard_GUID myDriverID=TFF->GetDriverGUID();

		Standard_CString aStrGuid= new char[256];
		myDriverID.ToCString(aStrGuid);
		CString szID(aStrGuid);
		szID.MakeUpper();
		delete[] aStrGuid;

		delete m_pShapeInfo;
		m_pShapeInfo = GetShapeInfoFactory().Create(szID); // need a factory for the ShapeInfo
		if(m_pShapeInfo == NULL)
		{
			ASSERT(FALSE);
			return ES_CONTINUE;
		}
		m_pShapeInfo->GetFromLabel(m_LabelSelected);
		m_pView->SendMessage(WM_GEOM_PROPACTION, GPA_SHOW_SELECTED_PROP, 0);

	}
	else
	{
		delete m_pEditorViewer;
		m_pEditorViewer = NULL;
	}

	return ES_CONTINUE;
}
EditorState CSelectEditor::OnLButtonUp(UINT nFlags, long x, long y)
{
	DrawRectangle(x,y,false);
	m_ptStart.x = x;
	m_ptStart.y = y;



	return ES_CONTINUE;
}

void CSelectEditor::OnMouseMove(UINT nFlags, long x, long y)
{
	if(nFlags & MK_LBUTTON)
	{
		DrawRectangle(x,y,true);
	}
	else
	{
		Selecter()->DynamicSense(x, y);
	}
	//GetRender()->MoveTo(x, y, GetView());
}

void CSelectEditor::DrawRectangle(long x, long y, bool bDraw)
{
	ASSERT(m_pView);

	CWnd* pWnd = CWnd::FromHandle(m_pView->GetOwnerWnd());
	CClientDC clientDC(pWnd);
	CPen* pOldPen = clientDC.SelectObject(m_pPen);

	clientDC.SetROP2(R2_NOTXORPEN);

	clientDC.Rectangle(m_ptStart.x, m_ptStart.y, m_ptEnd.x, m_ptEnd.y);
	if(bDraw)
	{
		clientDC.Rectangle(m_ptStart.x, m_ptStart.y, x, y);
		m_ptEnd.x = x;
		m_ptEnd.y = y;
	}

	clientDC.SelectObject(pOldPen);

}

CShapeInfo* CSelectEditor::GetShapeInfo()
{
	return m_pShapeInfo;
}

void CSelectEditor::OnChangeParam(UINT nID)
{
	ASSERT(m_pEditorViewer);
	if(!m_pEditorViewer || !m_pShapeInfo || m_LabelSelected.IsNull())
		return;

	m_pEditorViewer->OnChangeParam(nID);
	TFunction_Logbook log;
	if(!m_pShapeInfo->ModifyLabel(m_LabelSelected, log))
		return;
	
	Handle(TFunction_Function) TFF; 
	if ( !m_LabelSelected.FindAttribute(TFunction_Function::GetID(),TFF) )
		return;

	// Get the TFunction_FunctionDriver GUID used with the TFunction_Function
	Standard_GUID myDriverID=TFF->GetDriverGUID();
	Handle(TFunction_Driver) myDriver;
	TFunction_DriverTable::Get()->FindDriver(myDriverID, myDriver);

	myDriver->Init(m_LabelSelected);
	if (myDriver->MustExecute(log))
	{
		log.SetTouched(m_LabelSelected);
		if(myDriver->Execute(log)) // failed to execute
			return;

		// show it
		Handle(TPrsStd_AISPresentation) prs= TPrsStd_AISPresentation::Set(m_LabelSelected, TNaming_NamedShape::GetID()); 
		TDataStd_Integer::Set(m_LabelSelected, 1);
		prs->Display(1);
		GetRender()->UpdateCurrentViewer();
	}

}